home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / toollib / source / string.s < prev    next >
Text File  |  1995-12-30  |  21KB  |  395 lines

  1.                 opt     l+,o+,ow-
  2. *
  3. *   string.s version 8.1 - © Copyright 1990 Jaba Development
  4. *
  5. *   Author    : Jan van den Baard
  6. *   Assembler : Devpac version 2.14
  7. *
  8.  
  9.                 incdir  'sys:devpac_inc/'
  10.                 include 'mymacros.i'
  11.                 include 'exec/memory.i'
  12.                 include 'exec/exec_lib.i'
  13.                 include 'libraries/dos.i'
  14.                 include 'libraries/dos_lib.i'
  15.                 include 'tool.i'
  16.  
  17.                 xref    DoFmt
  18.                 xref    DoBuf
  19.                 xref    CharRight
  20.                 xref    CharLeft
  21.                 xref    StrCpy
  22.                 xref    ToUpper
  23.                 xref    ToLower
  24.                 xref    StrLen
  25.                 xref    StrCmp
  26.                 xref    StriCmp
  27.  
  28.                 xref    _DOSBase
  29.  
  30.                 xdef    Format
  31.                 xdef    WriteFormat
  32.                 xdef    MatchPattern
  33.                 xdef    Isolate
  34.                 xdef    BstrToCstr
  35.                 xdef    GetDate
  36.  
  37. Format:         movem.l a2-a3/a6,-(sp)
  38.                 move.l  a0,a3               ; buffer to a3
  39.                 move.l  a1,a0               ; format string to a0
  40.                 move.l  a2,a1               ; arguments (pointer!) to a1
  41.                 move.l  #DoBuf,a2           ; specal routine (support.s)
  42.                 move.l  (_SysBase).w,a6
  43.                 libcall RawDoFmt            ; format the output
  44.                 movem.l (sp)+,a2-a3/a6
  45.                 rts
  46.  
  47. WriteFormat:    movem.l d2-d3/a2-a3/a6,-(sp)
  48.                 movem.l a0-a2,-(sp)         ; stack arguments
  49.                 move.l  #512,d0             ; MAXIMUM OUTPUT SIZE!!!!
  50.                 moveq   #MEMF_PUBLIC,d1
  51.                 move.l  (_SysBase).w,a6
  52.                 libcall AllocMem            ; allocate buffer
  53.                 move.l  d0,-(sp)            ; stack buffer
  54.                 bne.s   MemOK
  55.                 lea.l   16(sp),sp           ; reset stack
  56.                 moveq   #-1,d0              ; -1 for error
  57.                 bra.s   FmtDone
  58. MemOK:          move.l  (sp),a3             ; buffer to a3
  59.                 move.l  8(sp),a0            ; format string to a0
  60.                 move.l  12(sp),a1           ; arguments (pointer!) to a1
  61.                 move.l  #DoBuf,a2           ; special routine (support.s)
  62.                 libcall RawDoFmt            ; format the output
  63.                 move.l  (sp),a0             ; buffer to a0
  64.                 bsr     StrLen              ; get the length
  65.                 move.l  d0,d3               ; put it in d3
  66.                 move.l  4(sp),d1            ; handle to d1
  67.                 move.l  (sp),d2             ; buffer to d2
  68.                 move.l  _DOSBase,a6
  69.                 libcall Write               ; write it to the handle
  70.                 move.l  (sp)+,a1            ; buffer to a1
  71.                 move.l  d0,-(sp)            ; stack Write return code
  72.                 move.l  #512,d0
  73.                 move.l  (_SysBase).w,a6
  74.                 libcall FreeMem             ; free the buffer
  75.                 move.l  (sp)+,d0            ; pull Write return code
  76.                 lea.l   12(sp),sp           ; reset the stack
  77. FmtDone:        movem.l (sp)+,d2-d3/a2-a3/a6
  78.                 rts
  79.  
  80.  
  81. MatchPattern:   move.l  d0,-(sp)
  82.                 movem.l a0-a1,-(sp)         ; push arguments
  83.                 bsr     Match               ; call Match
  84.                 lea.l   12(sp),sp           ; restore stack
  85.                 rts
  86. *
  87. * this is the actual pattern matching routine. It expects the parrameters
  88. * on the stack. It call's itself several times. recursive, needs some stack!
  89. *
  90. Match:          movem.l a2-a3/a5/d2,-(sp)
  91.                 move.l  20(sp),a2               ; str = a2
  92.                 move.l  24(sp),a3               ; pat = a3
  93.                 move.l  28(sp),d2               ; case flag
  94.                 move.l  a3,a0                   ; a0 = pat
  95.                 bsr     StrLen                  ; strlen(a0)
  96.                 tst.l   d0                      ; len == 0 ?
  97.                 bne.s   FOREVER                 ; no, there is a pattern
  98.                 moveq   #1,d0                   ; always return TRUE when no
  99.                 bra.s   TheEnd                  ; pattern is found.
  100. FOREVER:        move.b  (a2),d0                 ; d0 = *str
  101.                 tst.l   d2                      ; case check true ?
  102.                 bne.s   NotLow                  ; no
  103.                 bsr     ToLower                 ; tolower(d0)
  104. NotLow:         move.b  d0,d1                   ; d1 = d0
  105.                 move.b  (a3),d0                 ; d0 = *pat
  106.                 tst.l   d2                      ; case check true ?
  107.                 bne.s   NotLow1                 ; no
  108.                 bsr     ToLower                 ; tolower(d0)
  109. NotLow1:        cmp.b   d0,d1                   ; d0 == d1 ?
  110.                 bne.s   NotSameChar             ; no.. check for WildCards
  111.                 tst.b   (a2)+                   ; *str++ == 0 ?
  112.                 bne.s   AddPat                  ; no..
  113.                 moveq   #1,d0                   ; TRUE
  114. TheEnd:         movem.l (sp)+,a2-a3/a5/d2
  115.                 rts                             ; return
  116. AddPat:         inc.w   a3                      ; pat++
  117.                 bra.s   FOREVER                 ; loop
  118. NotSameChar:    cmp.b   #'?',(a3)               ; *pat == '?' ?
  119.                 bne.s   Artis                   ; no..
  120.                 tst.b   (a2)                    ; *str == 0   ?
  121.                 beq.s   Artis                   ; yes..
  122.                 inc.w   a3                      ; pat++
  123.                 inc.w   a2                      ; str++
  124.                 bra.s   FOREVER
  125. Artis:          cmp.b   #'*',(a3)               ; *pat == '*' ?
  126.                 beq.s   IsArt                   ; yes..
  127.                 cldat   d0                      ; FALSE
  128.                 bra.s   TheEnd                  ; return
  129. IsArt:          cmp.b   #'*',(a3)               ; *pat == '*' ?
  130.                 bne.s   DoAgain                 ; no..
  131.                 inc.w   a3
  132.                 tst.b   (a3)                    ; *++pat == 0 ?
  133.                 bne.s   IsArt                   ; no.. loop
  134.                 moveq   #1,d0                   ; TRUE
  135.                 bra.s   TheEnd                  ; return
  136. DoAgain:        move.l  a2,a0                   ; a0 = str
  137.                 bsr     StrLen                  ; strlen(a0)
  138.                 move.l  d0,a5                   ; a5 = len
  139.                 add.l   a2,a5                   ; a5 += str
  140.                 dec.w   a5                      ; a5--
  141.                 bra.s   CheckEnd1               ; check if all are done
  142. LoopIt:         move.b  (a5),d0                 ; d0 = *a5
  143.                 tst.l   d2                      ; check case flag
  144.                 bne.s   DoCase                  ; yes.. check the case
  145.                 bsr     ToLower                 ; make lower case
  146. DoCase:         move.b  d0,d1                   ; put char in d1
  147.                 move.b  (a3),d0                 ; d0 == *pat
  148.                 tst.l   d2                      ; check case flag
  149.                 bne.s   DoCase2                 ; yes.. check the case
  150.                 bsr     ToLower                 ; make lower case
  151. DoCase2:        cmp.b   d0,d1                   ; compare to chars
  152.                 bne.s   CheckEnd                ; check if all are done
  153.                 move.l  d2,-(sp)                ; push case flag
  154.                 move.l  a3,-(sp)                ; push pat
  155.                 move.l  a5,-(sp)                ; push a5
  156.                 bsr     Match                   ; Match(a5,a3,d2)
  157.                 lea     12(sp),sp               ; reset the stack
  158.                 tst.l   d0                      ; d0 == 0 ?
  159.                 beq.s   CheckEnd                ; yes.. check if all are done
  160.                 moveq   #1,d0                   ; TRUE
  161.                 bra     TheEnd                  ; return
  162. CheckEnd:       dec.w   a5                      ; a5--
  163. CheckEnd1:      cmp.l   a2,a5                   ; a5 >= str
  164.                 bcc.s   LoopIt                  ; yes loop
  165.                 cldat   d0                      ; FALSE
  166.                 bra     TheEnd                  ; return
  167.  
  168.  
  169. Isolate:        movem.l a2-a3/a6,-(sp)
  170.                 move.l  a0,a2                   ; fp = a2
  171.                 move.l  a1,a3                   ; b  = a3
  172.                 move.b  #'/',d0
  173.                 move.l  a2,a0
  174.                 bsr     CharRight               ; charright(fp,'/')
  175.                 tst.l   d0                      ; found ?
  176.                 bne.s   FoundChar               ; yes..
  177.                 move.b  #':',d0
  178.                 move.l  a2,a0
  179.                 bsr     CharLeft                ; charleft(fp,':')
  180.                 tst.l   d0                      ; found ?
  181.                 bne.s   FoundChar               ; yes..
  182.                 move.b  #'*',d0
  183.                 move.l  a2,a0
  184.                 bsr     CharRight               ; charright(fp,'*')
  185.                 tst.l   d0                      ; found ?
  186.                 bne.s   DoCopy                  ; yes..
  187.                 move.b  #'?',d0
  188.                 move.l  a2,a0
  189.                 bsr     CharRight               ; charright(fp,'?')
  190.                 tst.l   d0                      ; found ?
  191.                 beq.s   NoCopy                  ; no..
  192. DoCopy:         move.l  a3,a0                   ; dest = b
  193.                 move.l  a2,a1                   ; source = fp
  194.                 bsr     StrCpy                  ; StrCpy(b,fp)
  195.                 clr.b   (a2)                    ; fp[0] = 0
  196.                 moveq   #1,d0                   ; TRUE
  197.                 bra.s   EndIso                  ; return
  198. NoCopy:         clr.b   (a3)                    ; b[0] = 0
  199.                 cldat   d0                      ; FALSE
  200.                 bra.s   EndIso                  ; return
  201. FoundChar:      move.l  d0,a6                   ; adr to a6
  202.                 move.b  #'*',d0
  203.                 move.l  a6,a0
  204.                 bsr     CharLeft                ; charleft(adr,'*')
  205.                 tst.l   d0                      ; found ?
  206.                 bne.s   GotWild                 ; yes..
  207.                 move.b  #'?',d0
  208.                 move.l  a2,a0
  209.                 bsr     CharRight               ; charright(fp,'?')
  210.                 tst.l   d0                      ; found ?
  211.                 beq.s   NoWild                  ; no..
  212. GotWild:        inc.w   a6                      ; adr++
  213.                 move.l  a3,a0                   ; dest = b
  214.                 move.l  a6,a1                   ; source = adr
  215.                 bsr     StrCpy                  ; StrCpy(dest,source)
  216.                 clr.b   (a6)                    ; adr[1] = 0
  217.                 moveq   #1,d0                   ; TRUE
  218.                 bra.s   EndIso                  ; return
  219. NoWild:         clr.b   (a3)                    ; b[0] = 0
  220.                 cldat   d0                      ; FALSE
  221. EndIso:         movem.l (sp)+,a2-a3/a6
  222.                 rts                             ; return
  223.  
  224.  
  225. BstrToCstr:     add.l   a0,a0
  226.                 add.l   a0,a0                   ; BADDR(bstr)
  227.                 cldat   d0
  228.                 move.b  (a0)+,d0                ; size = bstr[0]
  229.                 bra.s   Begin                   ; begin loop
  230. Copy:           move.b  (a0)+,(a1)+             ; buf[i-1] = bstr[i]
  231. Begin:          dbra    d0,Copy                 ; loop until size bytes copied
  232.                 clr.b   (a1)                    ; buf[size] = 0
  233.                 rts                             ; return
  234.  
  235.  
  236. GetDate:        movem.l d2-d7/a2-a3/a5-a6,-(sp)
  237.                 move.l  d0,-(sp)
  238.                 movem.l a0-a1,-(sp)
  239.                 moveq   #ds_SIZEOF,d0           ; sizeof(struct DateStamp)
  240.                 moveq   #MEMF_PUBLIC,d1         ; MEMF_PUBLIC
  241.                 move.l  (_SysBase).w,a6
  242.                 libcall AllocMem                ; AllocMem(ds_SIZEOF,MEMF_PUBLIC)
  243.                 move.l  d0,a2                   ; pointer to a2
  244.                 bne.s   AllocOK                 ; if NULL allocation failed
  245.                 moveq   #0,d0                   ; FALSE
  246.                 bra     AllocFailed             ; return
  247. AllocOK:        move.l  4(sp),a3                ; buffer pointer to a3
  248.                 tst.l   (sp)                    ; passed a DateStamp ?
  249.                 beq.s   StampIt                 ; no.. system time
  250.                 move.l  (sp),a0                 ; your stamp as source
  251.                 moveq   #2,d0
  252. Doit:           move.l  (a0)+,(a2)+
  253.                 dbra    d0,Doit
  254.                 sub.l   #12,a2
  255.                 bra.s   Copied
  256. StampIt:        move.l  a2,d1                   ; buffer to d1
  257.                 move.l  _DOSBase,a6
  258.                 libcall DateStamp               ; DateStamp(buffer)
  259. Copied:         move.l  ds_Days(a2),d4          ; days to d4
  260.                 move.l  ds_Minute(a2),d0        ; minutes to d0
  261.                 divu    #60,d0                  ; devide by 60
  262.                 move.w  d0,d5                   ; low 16 bits is hours
  263.                 ext.l   d5                      ; long extension
  264.                 swap    d0                      ; high 16 bits is remainder (minutes)
  265.                 move.w  d0,d6                   ; to d6
  266.                 ext.l   d6                      ; long extension
  267.                 move.l  ds_Tick(a2),d0          ; ticks to d0
  268.                 divu    #TICKS_PER_SECOND,d0    ; devide by TICKS_PER_SECOND
  269.                 move.w  d0,d7                   ; low 16 bits is seconds
  270.                 ext.l   d7                      ; long extension
  271.                 tst.l   d4                      ; days < 0
  272.                 blt.s   ScrewedUp               ; if so, error
  273.                 tst.l   d6                      ; mins < 0
  274.                 blt.s   ScrewedUp               ; if so, error
  275.                 tst.l   d7                      ; secs < 0
  276.                 bge.s   DateOK                  ; if not,  OK
  277. ScrewedUp:      pea     su                      ; copy error string
  278.                 move.l  a3,-(sp)                ; into your buffer
  279.                 jsr     DoFmt
  280.                 addq.w  #8,sp                   ; reset stack
  281.                 moveq   #0,d0                   ; FALSE
  282.                 bra     EndGD                   ; return
  283. DateOK:         inc.l   d4                      ; days++
  284.                 move.l  #1978,d2                ; start at 1978
  285. YearLoop:       move.l  d2,d0                   ; year to d0
  286.                 divu    #4,d0                   ; devide by 4
  287.                 swap    d0                      ; swap for remainder
  288.                 tst.w   d0                      ; is there a remainder ?
  289.                 bne.s   NotLeap                 ; yes.. it's no leap year
  290.                 move.l  #366,d1                 ; 366 days in a leap year
  291.                 bra.s   CheckDays
  292. NotLeap:        move.l  #365,d1                 ; 365 days in a normal year
  293. CheckDays:      cmp.l   d1,d4                   ; days <= dayes_per_year
  294.                 ble.s   EndYear                 ; yes.. break
  295.                 sub.l   d1,d4                   ; days -= dayes_per_year
  296.                 inc.l   d2                      ; year++
  297.                 bra.s   YearLoop                ; loop
  298. EndYear:        cldat   d3                      ; mon = 0
  299. MonLoop:        cmp.l   #12,d3                  ; mon <= 12
  300.                 bgt.s   EndMon                  ; no.. break
  301.                 lea.l   dim,a0                  ; dayes_in_month table to a0
  302.                 move.l  d3,d0                   ; mon to d0
  303.                 add.l   d0,d0                   ; d0 * 2 for correct table offset
  304.                 move.w  (a0,d0.l),d1            ; dpm = dayes_per_month[mon]
  305.                 ext.l   d1                      ; long extension
  306.                 cmp.l   #1,d3                   ; is mon 1 ?
  307.                 bne.s   NotFeb                  ; no not february
  308.                 move.l  d2,d0                   ; year to d0
  309.                 divu    #4,d0                   ; devide by four
  310.                 swap    d0                      ; swap for remainder
  311.                 tst.w   d0                      ; is there a remainder ?
  312.                 bne.s   NotFeb                  ; yes.. it's not a leap year
  313.                 inc.l   d1                      ; else february has 29 days
  314. NotFeb:         cmp.l   d1,d4                   ; days <= dpm
  315.                 ble.s   EndMon                  ; yes.. break
  316.                 sub.l   d1,d4                   ; days -= dpm
  317.                 inc.l   d3                      ; mon++
  318.                 bra.s   MonLoop                 ; loop
  319. EndMon:         move.l  ds_Days(a2),d0          ; days to d0
  320.                 divu    #7,d0                   ; devide by 7
  321.                 swap    d0                      ; swap for remaider
  322.                 ext.l   d0                      ; long extension
  323.                 asl.l   #2,d0                   ; d0 * 4 for correct table offset
  324.                 lea     dys,a0                  ; days table to a0
  325.                 move.l  (a0,d0.l),a6            ; a6 = dayes[d0]
  326.                 lea.l   mnt,a0                  ; month table to a0
  327.                 asl.l   #2,d3                   ; d3 * 4 for correct table offset
  328.                 move.l  (a0,d3.l),a5            ; a5 = month[d3]
  329.                 cmp.l   #ONLY_DAY,8(sp)         ; do you want only the day ?
  330.                 bne.s   Date                    ; no.. branch
  331.                 move.l  a6,-(sp)                ; push day
  332.                 pea     j1                      ; push format string
  333.                 move.l  a3,-(sp)                ; push buffer
  334.                 bsr     DoFmt                   ; format the output
  335.                 lea.l   12(sp),sp               ; reset stack
  336.                 bra.s   Done                    ; return
  337. Date:           cmp.l   #ONLY_DATE,8(sp)        ; do you want only the date ?
  338.                 bne.s   Time                    ; no.. branch
  339.                 move.l  d2,-(sp)                ; push year
  340.                 move.l  a5,-(sp)                ; push month
  341.                 move.l  d4,-(sp)                ; push day
  342.                 pea     j2                      ; push format string
  343.                 move.l  a3,-(sp)                ; push buffer
  344.                 bsr     DoFmt                   ; format the output
  345.                 lea.l   20(sp),sp               ; reset stack
  346.                 bra.s   Done                    ; return
  347. Time:           cmp.l   #ONLY_TIME,8(sp)        ; do you want only the time ?
  348.                 bne.s   All                     ; no branch
  349.                 move.l  d7,-(sp)                ; push second
  350.                 move.l  d6,-(sp)                ; push minute
  351.                 move.l  d5,-(sp)                ; push hours
  352.                 pea     j3                      ; push format string
  353.                 move.l  a3,-(sp)                ; push buffer
  354.                 bsr     DoFmt                   ; format the output
  355.                 lea.l   20(sp),sp               ; reset stack
  356.                 bra.s   Done                    ; return
  357. All:            move.l  d7,-(sp)                ; push second
  358.                 move.l  d6,-(sp)                ; push minute
  359.                 move.l  d5,-(sp)                ; push hour
  360.                 move.l  d2,-(sp)                ; push year
  361.                 move.l  a5,-(sp)                ; push month
  362.                 move.l  d4,-(sp)                ; push day
  363.                 move.l  a6,-(sp)                ; push ascii day
  364.                 pea     j4                      ; push format string
  365.                 move.l  a3,-(sp)                ; push buffer
  366.                 bsr     DoFmt                   ; format the output
  367.                 lea.l   36(sp),sp               ; reset the stack
  368. Done:           moveq   #1,d0                   ; TRUE
  369. EndGD:          move.l  d0,-(sp)                ; push return code
  370.                 move.l  a2,a1                   ; date buffer to a1
  371.                 moveq   #ds_SIZEOF,d0           ; sizeof(struct DateStamp)
  372.                 move.l  (_SysBase).w,a6
  373.                 libcall FreeMem                 ; FreeMem(dbuf,ds_SIZEOF)
  374.                 move.l  (sp)+,d0                ; pull return code
  375. AllocFailed:    lea.l   12(sp),sp
  376.                 movem.l (sp)+,d2-d7/a2/a3/a5/a6
  377.                 rts                             ; return
  378.  
  379.                 even
  380. dim:            dc.w    31,28,31,30,31,30,31,31,30,31,30,31
  381. mnt:            dc.l    s+0,s+4,s+8,s+12,s+16,s+20,s+24,s+28,s+32,s+36,s+40,s+44
  382. dys:            dc.l    s+48,s+55,s+62,s+70,s+80,s+89,s+96
  383.                 even
  384. s:              dc.b    'Jan',0,'Feb',0,'Mar',0,'Apr',0,'May',0,'Jun',0
  385.                 dc.b    'Jul',0,'Aug',0,'Sep',0,'Oct',0,'Nov',0,'Dec',0
  386.                 dc.b    'Sunday',0,'Monday',0,'Tuesday',0,'Wednesday',0
  387.                 dc.b    'Thursday',0,'Friday',0,'Saterday',0
  388. su:             dc.b    'Date screwed up !',0
  389.                 even
  390. j1:             dc.b    '%-9ls',0
  391. j2:             dc.b    '%02.2ld-%3ls-%04.4ld',0
  392. j3:             dc.b    '%02.2ld:%02.2ld:%02.2ld',0
  393. j4:             dc.b    '%-9ls %02.2ld-%3ls-%04.4ld %02.2ld:%02.2ld:%02.2ld',0
  394.                 even
  395.